use sea_orm::{
    prelude::*,
    sea_query::{Expr, SimpleExpr},
};

#[derive(Debug, PartialEq, Eq, Clone, DeriveEntityModel)]
#[sea_orm(table_name = "view_book_pub_status")]
pub struct Model {
    #[sea_orm(primary_key, auto_increment = false)]
    pub id: i64,
    pub room_id: i64,
    pub day: Date,
    pub booked_time: u64,
    pub room_name: String,
    pub max_people: u32,
}

#[derive(Debug, Clone, Copy, PartialEq, EnumIter, DeriveRelation)]
pub enum Relation {}

impl ActiveModelBehavior for ActiveModel {}

pub fn time_range_able_condition(time_range: u64) -> SimpleExpr {
    Expr::cust_with_values(
        "(`view_book_pub_status`.`booked_time` & ?) = 0",
        vec![time_range],
    )
}

#[cfg(test)]
mod test_view {
    use sea_orm::Condition;

    use super::*;
    use crate::utils::test_conn::get_connection;
    #[tokio::test]
    async fn test_load() {
        let db = get_connection().await;

        let resp = Entity::find().all(db).await.expect("query Error");

        assert_eq!(resp.len(), 10);
    }
    #[tokio::test]
    async fn test_check_time_able() {
        let db = get_connection().await;

        let resp = Entity::find()
            .filter(
                Condition::all()
                    .add(time_range_able_condition(0b11000000000000000000))
                    .add(Column::Day.eq(Date::from_ymd(2022, 4, 23))),
            )
            .all(db)
            .await
            .expect("query error");

        assert_eq!(resp.len(), 10);
    }
    #[tokio::test]
    async fn test_unable_time() {
        let db = get_connection().await;

        let resp = Entity::find()
            .filter(
                Condition::all()
                    .add(time_range_able_condition(0b1111))
                    .add(Column::Day.eq(Date::from_ymd(2022, 4, 23))),
            )
            .all(db)
            .await
            .expect("db err");

        assert_eq!(resp.len(), 0);
    }
}
